c# Winform 多线程操作 |
您所在的位置:网站首页 › winform 爬虫 › c# Winform 多线程操作 |
主要是对一个过程需要的时间很长执行时会出现界面假死的情况 方法1: Application.DoEvents(),这种方法当你拖动窗体时,界面不会假死。但在你拖动时代码不再执行,也就是阻塞了,当你不再控制窗体时会继续执行,其实这还是一个单线程 for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { textBox1.Text = i.ToString() + " " + j.ToString(); Application.DoEvents(); } }
方法2:多线程 2.1:取消控件跨线程检测(不推荐有时会出现一些莫名奇妙的错误如控件不能加载等问题) 2.1.1取消窗体内控件的跨线程检查(单个控件取消也可以) public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false;//干掉检测 不再检测跨线程 }2.1.2新建线程实现跨线程访问 /// /// 新建线程并执行 /// /// /// private void button1_Click(object sender, EventArgs e) { ThreadStart thStart = new ThreadStart(Pro);//threadStart委托 Thread thread = new Thread(thStart); thread.Priority = ThreadPriority.Highest; thread.IsBackground = true; //关闭窗体继续执行 thread.Start(); } public void Pro() { for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { textBox1.Text = j.ToString(); } } }
2.2:主线程中操作(推荐) 2.2.1 不用取消跨线程访问 /// /// 新建线程并执行 /// /// /// private void button1_Click(object sender, EventArgs e) { ThreadStart thStart = new ThreadStart(Pro);//threadStart委托 Thread thread = new Thread(thStart); thread.Priority = ThreadPriority.Highest; thread.IsBackground = true; //关闭窗体继续执行 thread.Start(); } public void Pro() { for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { if (textBox1.InvokeRequired)//不同线程访问了 textBox1.Invoke(new Action(SetTxtValue), textBox1, j.ToString());//跨线程了 else//同线程直接赋值 textBox1.Text = j.ToString(); } } } private void SetTxtValue(TextBox txt, string value) { txt.Text = value; }注:多个线程同时访问一个方法时 需要锁定 public static readonly object obj = new object(); public void Pro() { //lock(obj){}=Monitor.Enter(obj) Monitor.Exit(obj) lock (obj) { for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { if (textBox1.InvokeRequired)//不同线程访问了 textBox1.Invoke(new Action(SetTxtValue), textBox1, j.ToString());//跨线程了 else//同线程直接赋值 textBox1.Text = j.ToString(); } } } }
3.窗体与自定义类之间的多线程操作(适用数据量大查询速度慢时 让数据在新线程中查询 防主线程卡死) 3.1自定义类中定义事件,并定义各事件执行的步骤方法 3.2窗体中实现类,并生成类各事件,在多线程中执行自定义类的步骤方法 3.3 代码3.1 ![]() ![]() 3.4 代码3.2 ![]() ![]() 3.5 结果如下图
task任务与thread大同小异 使用时 尽量少的让控件跨线程 可通过ref 或 out 对参数传出 检测线程结束 再给控件赋值 也可用task的wait方法 4 异步回调 ![]() ![]()
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |